package smlab.manager
{
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.KeyboardEvent;
	import flash.utils.Dictionary;
	
	/**
	 * 键盘管理类
	 * @author simon
	 * 
	 */
	public class KeyboardManager_SM extends EventDispatcher
	{
		static private var _instance:KeyboardManager_SM;
		private var _stage:Stage;
		private var _keyboardEventMap:Dictionary=new Dictionary;
		private var _keyCodeMap:Dictionary=new Dictionary;
		private var _functionMap:Dictionary=new Dictionary;
		private var _idArr:Array=[];
		
		public function KeyboardManager_SM()
		{
			if(_instance)throw new Error("KeyboardManager_SM_singleton_Error");
		}
		
		static public function getInstance():KeyboardManager_SM{
			if(!_instance)_instance=new KeyboardManager_SM;
			return _instance;
		}
		
		/**
		 * 必须先设置 stage 才可以开始监听键盘事件（只需设置一次，但也可以多次）
		 * @param s
		 * 
		 */
		public function set stage(s:Stage):void{
			_stage=s;
		}
		
		/**
		 * 监听单键按下
		 * @param keyboardEvent
		 * @param keyCode
		 * @param fun
		 * @param id              此次添加的监听的唯一key 用于删除监听
		 * 
		 */
		public function addListener(keyboardEvent:String,keyCode:uint,fun:Function,id:int=0):void
		{
			if(!keyboardEvent || !keyCode || fun==null){
				if(keyboardEvent!=KeyboardEvent.KEY_DOWN && keyboardEvent!=KeyboardEvent.KEY_UP){
					trace("KeyboardManager_SM.addListener()::parameter wrong~!");
					return;
				}
			}
			
			if(_idArr.indexOf(id) != -1){
				trace("重复添加了键盘监听! id："+id+",为避免冲突,程序会先删除旧监听，然后再自动添加！");
				removeListener(id);
			}
			_keyboardEventMap[id]=keyboardEvent;
			_keyCodeMap[id]=keyCode;
			_functionMap[id]=fun;
			_idArr.push(id);
			_stage.addEventListener(keyboardEvent,KeyboardHandler);
		}
		
		public function removeListener(id:int=0):void
		{
			if(_idArr.length==0){
				return;
			}
			
			if(_idArr.indexOf(id)==-1){
				return;
			}
			
			var temp:Array=[];
			for(var i:int=0;i<_idArr.length;i++){
				if(_idArr[i]!=id){
					temp.push(_idArr[i]);
				}
			}
			_idArr=temp;
			
			if(_idArr.length<1){
				_stage.removeEventListener(_keyboardEventMap[id],KeyboardHandler);
			}
			
			_keyboardEventMap[id]=null;
			delete _keyboardEventMap[id];
			
			_keyCodeMap[id]=null;
			delete _keyCodeMap[id];
			
			_functionMap[id]=null;
			delete _functionMap[id];
		}
		
		private function KeyboardHandler(e:KeyboardEvent):void{
			for(var i:int=0;i<_idArr.length;i++){
				if(_keyboardEventMap[_idArr[i]]==e.type){
					if(_keyCodeMap[_idArr[i]]==e.keyCode){
						_functionMap[_idArr[i]]();
					}
				}
			}
		}
		
		//////////////////////////////////////////////////////////////////////////////
		
		/**
		 * 监听是否 CTRL+SHIFT+~ 三个键同时按下( 用来弹出聊天面板 )
		 * @param stage
		 * 
		 */
		public function listener_Ctrl_Shift_192():void{
			_stage.addEventListener(KeyboardEvent.KEY_DOWN,Ctrl_Shift_192_Handler);
			_stage.addEventListener(KeyboardEvent.KEY_UP,Ctrl_Shift_192_Handler);
		}
		
		public function remove_Ctrl_Shift_192():void{
			_stage.removeEventListener(KeyboardEvent.KEY_DOWN,Ctrl_Shift_192_Handler);
			_stage.removeEventListener(KeyboardEvent.KEY_UP,Ctrl_Shift_192_Handler);
		}
		
		private var _isCAP:Boolean=false;
		public static const CTRL_SHIFT_192_DOWN:String="ctrl_shift_192_down";
		public static const CTRL_SHIFT_192_UP:String="ctrl_shift_192_up";
		
		private function Ctrl_Shift_192_Handler(e:KeyboardEvent):void{
			if(e.type==KeyboardEvent.KEY_DOWN){
				if(e.ctrlKey && e.shiftKey){
					if(e.keyCode==192){
						if(_isCAP){
							return;
						}
						_isCAP=true;
						trace("同时按下了 CTRL+SHIFT+~");
						dispatchEvent(new Event(CTRL_SHIFT_192_DOWN));
					}
				}
			}
			if(e.type==KeyboardEvent.KEY_UP){
				if(e.keyCode== e.shiftKey || e.keyCode==e.altKey || e.keyCode==192){
					trace("您松开了 CTRL、SHIFT、~ 中的一个键");
					_isCAP=false;
					dispatchEvent(new Event(CTRL_SHIFT_192_UP));
				}
			}
			
		}
		
	}
}